﻿using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using Tambourine.Model;

namespace Tambourine.ViewModel
{
    public class TambourineVModel : INotifyPropertyChanged
    {

        private TestSuite tambourine;
        public TestSuite Data
        {
            get { return tambourine; }
            private set
            {
                tambourine = value;
                OnPropertyChanged("Data");
            }
        }

        private string filePath;
        public string FilePath
        {
            get { return filePath; }
            set
            {
                filePath = value;
                OnPropertyChanged("FilePath");
                OnPropertyChanged("Title");
            }
        }

        public string Title { get { return "NUnitTambourine " + FilePath; } }

        private TestCortegeMatrix currentMatrix;
        public TestCortegeMatrix CurrentMatrix
        {
            get { return currentMatrix; }
            set
            {
                currentMatrix = value;
                OnPropertyChanged("CurrentMatrix");
            }
        }

        #region OpenFileCommand
        private ICommand openFileCommand;
        public ICommand OpenFileCommand
        {
            get
            {
                if (openFileCommand == null)
                    openFileCommand = new RelayCommand(p => OpenFile());

                return openFileCommand;
            }
        }

        private void OpenFile()
        {
            string newFileName = showOpenFileDialog();
            LoadDataFromFile(newFileName);
        }

        #endregion OpenFileCommand

        #region ReloadFileCommand
        private ICommand reloadFileCommand;
        public ICommand ReloadFileCommand
        {
            get
            {
                if (reloadFileCommand == null)
                {
                    reloadFileCommand = new RelayCommand(
                        p => LoadDataFromFile(filePath),
                        p => File.Exists(filePath)
                    );
                }
                return reloadFileCommand;
            }
        }

        #endregion LoadFileCommand

        public void LoadDataFromFile(string filePath)
        {
            try
            {
                if (Data == null)
                    Data = new TestSuite(filePath);
                else
                    Data.Load(filePath);

                if (Data.Any())
                    CurrentMatrix = Data.First();

                FilePath = filePath;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Error occured!");
            }
        }

        #region ExportAllCommand
        private ICommand exportAllCommand;
        public ICommand ExportAllCommand
        {
            get
            {
                if (exportAllCommand == null)
                {
                    exportAllCommand = new RelayCommand(
                        p => exportAll(),
                        p => canExportAll()
                    );
                }
                return exportAllCommand;
            }
        }

        private void exportAll()
        {
            try
            {
                string fileName = showSaveFileDialog();
                Data.ExcelExport(fileName);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Error occured!");
            }
        }

        private bool canExportAll()
        {
            if (Data == null)
                return false;
            if (!Data.Any())
                return false;
            return true;
        }

        #endregion ExportAllCommand

        #region ExportOneCommand

        private ICommand exportOneCommand;
        public ICommand ExportOneCommand
        {
            get
            {
                if (exportOneCommand == null)
                {
                    exportOneCommand = new RelayCommand(
                        p => exportOne(CurrentMatrix),
                        p => canExportOne(CurrentMatrix)
                    );
                }
                return exportOneCommand;
            }
        }

        private void exportOne(TestCortegeMatrix currentMatrix)
        {
            try
            {
                string fileName = showSaveFileDialog();
                Data.ExcelExport(fileName, currentMatrix.Name);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Error occured!");
            }
        }

        private bool canExportOne(TestCortegeMatrix currentMatrix)
        {
            if (Data == null)
                return false;
            if (currentMatrix == null)
                return false;
            if (!Data.Any(a => a.Name == currentMatrix.Name))
                return false;
            return true;
        }

        #endregion ExportOneCommand

        #region INotifyPropertyChanged Members

        /// <summary>
        /// Raised when a property on this object has a new value.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Raises this object's PropertyChanged event.
        /// </summary>
        /// <param name="propertyName">The property that has a new value.</param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }

        #endregion // INotifyPropertyChanged Members

        #region file dialog functions

        private string showOpenFileDialog()
        {
            // Configure open file dialog box
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.FileName = "TestResult.xml"; // Default file name
            dlg.DefaultExt = ".xml"; // Default file extension
            dlg.Filter = "NUnit report (.xml)|*.xml"; // Filter files by extension

            // Show open file dialog box
            bool weHaveResult = (bool)dlg.ShowDialog();

            // Process open file dialog box results
            return weHaveResult ? dlg.FileName : null;
        }

        private string showSaveFileDialog()
        {
            // Configure save file dialog box
            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.FileName = "TestResult.xlsx"; // Default file name
            dlg.DefaultExt = ".xlsx"; // Default file extension
            dlg.Filter = "Excel file (.xlsx)|*.xlsx"; // Filter files by extension

            // Show save file dialog box
            bool weHaveResult = (bool)dlg.ShowDialog();

            // Process save file dialog box results
            return weHaveResult ? dlg.FileName : null;
        }

        #endregion file dialog functions

        internal void Run(string inputFile, string outputFile, string testName)
        {
            if (inputFile == null)
                return;

            LoadDataFromFile(inputFile);

            if(outputFile != null)
            {
                try
                {
                    if (FilePath != null)
                        Data.ExcelExport(outputFile, testName);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message, "Error occured!");
                }
            }
        }
    }
}
